package com.org.service.impl;

import com.org.DTO.LoginDTO;
import com.org.DTO.RegitryDTO;
import com.org.DTO.UpdateUserPasswordDTO;
import com.org.clients.HttpClient;
import com.org.context.BaseContext;
import com.org.entity.User;
import com.org.exception.BaseException;
import com.org.exception.ServerException;
import com.org.mapper.UserLoginMapper;
import com.org.message.BaseMessage;
import com.org.properties.JwtProperties;
import com.org.properties.RedisKeyPropertis;
import com.org.service.UserLoginService;
import com.org.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import jakarta.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserLoginServiceImpl implements UserLoginService {

    private static final String EMAIL_CODE_URL = "http://localhost:8080/pc/email/check";

    @Autowired
    private UserLoginMapper userLoginMapper;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 登录
     * @param loginDTO
     * @TODO 目前只实现了用户名登录，待优化-微信登录-QQ登录-邮箱登录
     * @return
     */
    @Override
    public String login(LoginDTO loginDTO, HttpSession session) {
        //一、判断登录方式
        User user = null;
        if(loginDTO.getUsername() != null && !loginDTO.getUsername().isEmpty()){
            //一.1、账号登录
            user = usernameLogin(loginDTO, session);
        }else if (loginDTO.getPhone() != null && !loginDTO.getPhone().isEmpty()){
            //一.2、TODO 手机号登录
            System.out.println("手机号登录");
        }else if(loginDTO.getEmail() != null && !loginDTO.getEmail().isEmpty()){
            //三.3、邮箱登录
            user = emailLogin(loginDTO);
        }else if (loginDTO.getQqPhone() != null && !loginDTO.getQqPhone().isEmpty()){
            //四.4、TODO QQ登录
            System.out.println("QQ登录");
        }else if (loginDTO.getWxPhone() != null && !loginDTO.getWxPhone().isEmpty()){
            //五.5、TODO 微信登录
            System.out.println("微信登录");
        }else{
            throw new BaseException("无效用户");
        }
        //四、生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        String token = JwtUtil.createJWT(jwtProperties.getPcSecretKey(), jwtProperties.getPcTtl(), claims);
        //五、返回token
        return token;
    }

    private User emailLogin(LoginDTO loginDTO) {
        System.out.println("邮箱登录");
        //1、验证验证码
        HashMap<String, String> params = new HashMap<>();
        params.put("email", loginDTO.getEmail());
        params.put("code", loginDTO.getCaptcha());
        String response = HttpClient.doGet(EMAIL_CODE_URL, params, null);
        if(!response.equals("true")){
            throw new BaseException("验证码错误");
        }
        //2、查询数据库
        User user = userLoginMapper.findUserByEmail(loginDTO.getEmail());
        return user;
    }

    private User usernameLogin(LoginDTO loginDTO, HttpSession session) {
        //一、判断格式是否正确
        if(loginDTO.getUsername() == null || loginDTO.getPassword() == null){
            throw new BaseException("用户名或密码不能为空");
        }
        //二、查询数据库是否存在该用户
        //将密码转成md5加密
        loginDTO.setPassword(DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes()));
        User user = userLoginMapper.findUser(loginDTO);
        //判断用户是否为空
        if (user == null) {
            throw new BaseException("用户不存在,请先注册！");
        }
        //三、判断密码是否正确
        if(!(loginDTO.getPassword().equals(user.getPassword()))){
            throw  new BaseException("密码错误");
        }
        //三、判断验证码
        String captcha = (String) session.getAttribute("captcha");
        if(captcha == null || !captcha.equals(loginDTO.getCaptcha())){
            throw new BaseException("验证码错误");
        }
        return user;
    }

    /**
     * 查询用户信息
     * @return
     */
    @Override
    public User findUser() {
        //一、获取当前用户id
        Long userId = BaseContext.getCurrentId();
        //二、查询数据库并返回
        return userLoginMapper.findUserById(userId);
    }

    /**
     * 修改用户信息
     * @param user
     */
    @Override
    public void updateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        //查询当前用户的旧数据
        User oldUser = findUser();
        int index = userLoginMapper.updateUser(user);
        if(index > 0){
            if(!user.getImage().isEmpty() && user.getImage() != null){
                if(!user.getImage().equals(oldUser.getImage())){
                    //删除redis中旧的图片
                    stringRedisTemplate.opsForSet().remove(RedisKeyPropertis.REDIS_KEY_UP_USE, oldUser.getImage());
                    //将图片路径添加到redis
                    stringRedisTemplate.opsForSet().add(RedisKeyPropertis.REDIS_KEY_UP_USE, user.getImage());
                }
            }

        }
    }

    /**
     * 注册
     * @param regitryDTO
     */
    @Override
    public void regitry(RegitryDTO regitryDTO) {
        //判断格式是否正确
        if(regitryDTO.getUsername() == null || regitryDTO.getPassword() == null){
            throw new BaseException("用户名或密码不能为空");
        }
        //判断用户名是否已存在
        //查询数据库
        LoginDTO loginDTO = new LoginDTO();
        BeanUtils.copyProperties(regitryDTO, loginDTO);
        User user = userLoginMapper.findUser(loginDTO);
        if(user != null){
            throw new BaseException("用户已存在");
        }
        //构建用户对象
        user= new User();
        user.setUsername(regitryDTO.getUsername());
        user.setPassword(DigestUtils.md5DigestAsHex(regitryDTO.getPassword().getBytes()));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setNickname(regitryDTO.getUsername() + "用户");

        //插入数据库
        userLoginMapper.regitryUser(user);
    }

    /**
     * 修改用户密码
     * @param updateUserPasswordDTO
     */
    @Override
    public void updateUserPassword(UpdateUserPasswordDTO updateUserPasswordDTO) {
        //判断格式是否正确
        if(updateUserPasswordDTO.getOldPassword() == null || updateUserPasswordDTO.getNewPassword() == null){
            throw new BaseException("新旧密码不能为空");
        }
        updateUserPasswordDTO.setId(BaseContext.getCurrentId());
        updateUserPasswordDTO.setOldPassword(DigestUtils.md5DigestAsHex(updateUserPasswordDTO.getOldPassword().getBytes()));
        //判断旧密码是否正确
        User user = userLoginMapper.findUserById(updateUserPasswordDTO.getId());
        if(!(updateUserPasswordDTO.getOldPassword().equals(user.getPassword()))){
            throw new BaseException("旧密码错误");
        }
        //判断新密码是否一致
        if(!(updateUserPasswordDTO.getNewPassword().equals(updateUserPasswordDTO.getConfirmPassword()))){
            throw new BaseException("新密码不一致");
        }
        //修改密码
        updateUserPasswordDTO.setNewPassword(DigestUtils.md5DigestAsHex(updateUserPasswordDTO.getNewPassword().getBytes()));
        userLoginMapper.updateUserPassword(updateUserPasswordDTO);
    }

    /**
     * 删除用户
     * @param id
     */
    @Override
    public void destroy(Long id) {
        User oldUser = findUser();
        int index = userLoginMapper.destroy(id);
        if(index > 0){
            //删除redis中旧的图片
            stringRedisTemplate.opsForSet().remove(RedisKeyPropertis.REDIS_KEY_UP_USE, oldUser.getImage());
        }
    }

    /**
     * 绑定邮箱
     * @param email 邮箱
     * @param code 验证码
     * @return
     */
    @Override
    public void bindEmail(String email, String code) {
        //1.判断邮箱是否不为空
        if(email != null){
            //1.1、判断邮箱格式是否正确
            if(!(email.matches("^[a-zA-Z0-9_+-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z]{2,}$"))){
                throw new BaseException("邮箱格式错误");
            }
            //1.2、格式正确

        }else{
            throw new BaseException("邮箱不能为空");
        }
        //2.调用验证验证码请求
        //2.1.构建参数
        Map<String, String> params = new HashMap<>();
        params.put("email", email);
        params.put("code", code);
        String getEmailCheck = HttpClient.doGet(EMAIL_CODE_URL, params, null);
        if(getEmailCheck == null){
            log.error("验证邮箱的请求服务异常");
            throw new ServerException(BaseMessage.SERVER_ERROR);
        }
        System.out.println("=====>" + getEmailCheck);

        //3.判断验证码是否正确
        if(!(getEmailCheck.equals("true"))){
            throw new BaseException(BaseMessage.CAPTCHA_ERROR);
        }
        //3.1、判断邮箱是否已存在
        User userEquals = userLoginMapper.findUserById(BaseContext.getCurrentId());
        if(userEquals.getEmail() != null){
            if(userEquals.getEmail().equals(email)){
                throw new BaseException("该邮箱已绑定，无需重复绑定");
            }
        }
        //3.2、查找该邮箱是否有绑定其他账号
        User user = userLoginMapper.findUserByEmail(email);
        //3.2.1、有绑定其他账号
        if(user != null){
            throw new BaseException("该邮箱已绑定账号" + user.getUsername());
        }
        //4.修改用户信息
        User userIndex = new User();
        userIndex.setId(BaseContext.getCurrentId());
        userIndex.setEmail(email);
        updateUser(userIndex);
    }
}
